﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Crucible.Models;
using WebMatrix.WebData;

namespace Crucible.Controllers
{
    public class CommentController : ApiController
    {
        private ArgumentConnection db = new ArgumentConnection();



        // GET api/Comment/AssertionComments/5
        [HttpGet]
        public IEnumerable<Object> NodeComments(int id)
        {
            //var comments = db.Comments.Where(c => c.Assertion_Id == id).Include(c => c.Author).AsNoTracking();
            var comments = (from com in db.Comments where com.Node_Id == id 
                           select new { com.Id, com.Parent_Id, com.Node_Id, com.Body, com.Score, com.DateAdded, com.Author, com.IsDeleted }).ToList();

            var nullAuthor = new UserProfile() { UserId = 0, UserName = "" };

            return
                (from com in comments 
                 select new {
                     com.Id, 
                     com.Parent_Id, 
                     com.Node_Id, 
                     Body = com.IsDeleted ? null : com.Body,
                     com.Score, 
                     Author = com.IsDeleted ? nullAuthor : com.Author,
                     DateAdded = AssertionHelper.FriendlyDate(com.DateAdded),
                     com.IsDeleted
                 }).AsEnumerable();
        }


        // GET api/Comment
        //public IEnumerable<Comment> GetComments()
        //{
        //    var comments = db.Comments.Include(c => c.Author).Include(c => c.Parent);
        //    return comments.AsEnumerable();
        //}

        // GET api/Comment/5
        //public Comment GetComment(int id)
        //{
        //    Comment comment = db.Comments.Find(id);
        //    if (comment == null)
        //    {
        //        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        //    }

        //    return comment;
        //}

        // PUT api/Comment/5
        [Authorize]
        public HttpResponseMessage PutComment(int id, Comment comment)
        {
            if (id != comment.Id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
            
            var c = db.Comments.Find(id);
            if (WebSecurity.CurrentUserId != c.Author_UserId)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Forbidden));
            }

            c.Body = comment.Body;
            db.Entry(c).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        // POST api/Comment
        [Authorize]
        public HttpResponseMessage PostComment(Comment comment)
        {

            if (comment.Author_UserId == 0)
            {
                comment.Author_UserId = WebSecurity.CurrentUserId;
            }

            if (comment.Author_UserId != WebSecurity.CurrentUserId)
            {
                throw new HttpException(403, "User Id is not authenticated.");
            }
            
            db.Comments.Add(comment);
            db.SaveChanges();

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, comment);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = comment.Id }));
            return response;
        }

        // DELETE api/Comment/5
        public HttpResponseMessage DeleteComment(int id)
        {
            Comment comment = db.Comments.Find(id);
            if (comment == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            if (WebSecurity.CurrentUserId != comment.Author_UserId)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Forbidden));
            }
            
            if (!(comment.Parent_Id > 0) && db.Comments.Any(child => child.Parent_Id == id)) // this comment has children
            {
                comment.IsDeleted = true;
            }
            else
            {
                db.Comments.Remove(comment);
            }

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            return Request.CreateResponse(HttpStatusCode.OK, comment);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}